/*
* Copyright 2010 tekhniaG authors
*
* Licensed under the LGPL, Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.gnu.org/licenses/lgpl.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tekhnia.com.tgraphs.ui.serialization
{
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	
	import mx.core.IVisualElement;
	import mx.core.IVisualElementContainer;
	
	/**
	 * 
	 * this class allows a graphic object to be serialized to an XML file
	 * @author Victor Andritoiu
	 * 
	 */
	public class GraphicObjectSerializer {
		/**
		 * 
		 * @private
		 * objects library descriptor
		 * 
		 */
		private var _libDescriptor: Array;
		
		/** 
		 * 
		 * constructor
		 * @param libraryInfo a description of the objects library to be managed. The description is
		 * an array as following: [{name: getQualifiedClassName(<classame>), properties: [<property1>,...,<propertyN>]}, ...]
		 *
		 */ 
		public function GraphicObjectSerializer(libraryInfo: Array): void {
			_libDescriptor = libraryInfo;
		}
		
		/** 
		 * 
		 * object to XML
		 * 
		 */
		public function obj2xml(o: *): XML {
			var root: XML = <graphicObject></graphicObject>;
			root.@className = getQualifiedClassName(o);
			for each (var go: * in _libDescriptor) {
				if (go["name"] == root.@className) {
					for each (var p: String in go["properties"]) {
						var property: XML = <property/>;
						property.@name = p;
						property.@value = o[p];
						root.appendChild(property);
					}
				}
			}
			
			trace(root.toXMLString());
			return root;
		}
		
		/** 
		 * 
		 * XML to object
		 * 
		 */
		public function xml2obj(xml: XML): * {
			var className: String = xml.@className;
			var oClass: Class = Class(getDefinitionByName(className));
			var result: Object = new oClass();
			
			for each (var pxml: XML in xml.property) {
				var pname: String = pxml.@name;
				var pvalue: String = pxml.@value;
				if (pvalue == "") {
					result[pname] = pvalue;
				} else if (!isNaN(Number(pvalue))) {
					result[pname] = Number(pvalue);
				} else if (pvalue.search(",") > 0) {
					var a: Array = pvalue.split(",");
					result[pname] = a;
				} else {
					result[pname] = pvalue;
				}
			}
			return result;
		}
		
		/** 
		 * 
		 * save objects to XML contained in a display container
		 * 
		 */
		public function save2xml(parent: IVisualElementContainer, filename: String): void {
			var xmlName: String = (new File(filename).name).split(".")[0];			
			var xml: XML = <tekhniaG/>;
			xml.@name = xmlName;
			for (var i: uint = 0; i < parent.numElements; i++) {
				xml.appendChild(obj2xml(parent.getElementAt(i)));
			}
			try {
				var file: File = new File(filename);
				var fs: FileStream = new FileStream();
				fs.open(file, FileMode.WRITE);
				fs.writeMultiByte(xml.toXMLString(), "utf-8");
				fs.close();
			} catch (e: Error) {
				trace(e.message);
			}
		}
		
		/** 
		 * 
		 * open objects from XML file and push them to a display container
		 * 
		 */
		public function openxml(parent: IVisualElementContainer, filename: String): void {
			var xml: XML;
			var file: File = new File(filename);
			var fs: FileStream = new FileStream();
			try {
				fs.open(file, FileMode.READ);
				xml = XML(fs.readMultiByte(file.size, "utf-8"));
				fs.close();
			} catch (e: Error) {
				trace(e.message);
				return;
			}
			
			for each (var goxml: XML in xml.graphicObject) {
				var o: Object = xml2obj(goxml);
				parent.addElement(o as IVisualElement);
			}
		}
	}
}